﻿#pragma once

#include "application.hpp"
#include "multicast_acceptor.hpp"
#include "multicast_sender.hpp"
#include <memory>

#include "broadcast_acceptor.hpp"
#include "broadcast_sender.hpp"
#include "device_info.hpp"
#include "json_object_io.hpp"


class Server : public app::Application<Server>
{
    struct Params
    {
#if defined (_WIN32)
        std::string network_interface_name = u8"以太网";
#elif defined (__linux__)
        std::string network_interface_name = u8"eth1";
#endif

        std::string address_multicast = "224.1.1.100";
        uint16_t port_multicast_receiver = 5555;
        uint16_t port_broadcast_receiver = 6666;

        DeviceInfo device_info;

        JSON_REFLECTION(
            Params,
            network_interface_name,
            port_multicast_receiver,
            address_multicast,
            port_broadcast_receiver,
            device_info)
    };
public:
    bool onInit();
    int onRun();
    void onCleanup();

protected:
    void onDataReceived(const std::vector<uint8_t>& data, const std::string& ip, uint16_t port);

    void onHandleDeviceSearch(const nlohmann::json& body, const std::string& ip, uint16_t port);
    void onHandleDeviceModify(const nlohmann::json& body, const std::string& ip, uint16_t port);
    void onHandleDeviceTimeSet(const nlohmann::json& body, const std::string& ip, uint16_t port);
    void onHandleDeviceTimeGet(const nlohmann::json& body, const std::string& ip, uint16_t port);

private:
    Params params;
    std::shared_ptr<MulticastAcceptor> sp_multicast_acceptor;
    std::shared_ptr<MulticastSender> sp_multicast_sender;
    std::shared_ptr<BroadcastSender> sp_broadcast_sender;
    std::shared_ptr<BroadcastAcceptor> sp_broadcast_acceptor;

};
